<?php
namespace App\Socket\Logic;

class CheckOutCards{
    private $outCards = [];
    private $outInfo;
    private $currentInfo;
    public function __construct($outCards=[],$currenInfo=null){     
        foreach($outCards as $cardData){
            $this->outCards[] = new Card($cardData["name"],$cardData["color"]);
        }
        //对牌进行重小到大排序
        usort($this->outCards,function($a,$b){
            return $a->getValue()-$b->getValue();
        });

        $this->currentInfo = $currenInfo;
       
    }

    public function check(){            

        
        $outInfo = $this->getOutCardsInfo();
        $this->outInfo = $outInfo;

        

        if(!$outInfo["type"]){
            //无牌型 不能出牌
            return false;
        }

        if(!$this->currentInfo){
            //当前无牌，不用对比，可直接出牌
            return $outInfo;
        }
        

        //对比牌型牌值
        if($this->checkCardTypeValue()){
            return $outInfo;
        }else{
            return false;
        }
    }

    /** 获取出牌信息 */
    private function getOutCardsInfo(){
        //检测outCards的牌型与出牌值
        $funs = ["isRocket","isBoom","isSingle","isDouble","isThree","isThreeOne","isThreeTwo","isQueue","isDoubleQueue","isThreeQueue","isPlainOne","isPlainTwo"];
        $outInfo = [
            "type"=>"",
            "value"=>0,
            "count"=>count($this->outCards)
        ];

        
        foreach($funs as $fun){            
            
            $value = $this->$fun();

            if($value!==false){
                $outInfo["type"] =  trim($fun,"is") ;
                $outInfo["value"] = $value;
                break;                
            }            
            
        }        
        return $outInfo;
    }

    private function checkCardTypeValue(){
        $outInfo = $this->outInfo;
        $current = $this->currentInfo;
     
        //设置牌型值
        $CardTypeValue=[
            "Rocket"=>9999,
            "Boom"=>100,
            "Single"=>1,
            "Double"=>1,
            "Three"=>1,            
            "ThreeOne"=>1,
            "ThreeTwo"=>1,
            "Queue"=>1,
            "DoubleQueue"=>1,
            "ThreeQueue"=>1,
            "PlainOne"=>1,
            "PlainTwo"=>1,
        ];

        if( $CardTypeValue[$outInfo["type"]] > $CardTypeValue[$current["type"]] ){
            return true;
        }else{
            //如果是相同牌型
            //1 先判断牌数
            if($outInfo["count"]!=$current["count"]) return false;
            //2 判断牌值
            if($outInfo["value"]>$current["value"]) return true;            
        }
        return false;
    }

    //火箭 大小王 2张牌
    private function isRocket(){
        if( count($this->outCards) !=2) return false;
        if($this->outCards[0]->getValue()+$this->outCards[1]->getValue()==27){
            return 9999;
        }else{
            return false;
        }
    }

    //炸弹 4张相同牌
    private function isBoom(){
        if( count($this->outCards) !=4) return false;
        $v1 = $this->outCards[0]->getValue();
        for($i=1;$i<count($this->outCards);$i++){
            if($this->outCards[$i]->getValue()!=$v1){
                return false;
            }
        }
        return $v1;
    }
    
    //单张 1张
    private function isSingle(){
        if( count($this->outCards) !=1 ) return false;
        return $this->outCards[0]->getValue();
    }

    //对子 2张相同牌
    private function isDouble(){
        if( count($this->outCards) !=2 ) return false;     
        $v1 = $this->outCards[0]->getValue();
        $v2 = $this->outCards[1]->getValue();
        if($v1!=$v2) return false;
        return $v1;
    }

    //三张 3张相同牌
    private function isThree(){
        if( count($this->outCards) !=3 ) return false;
        $v1 = $this->outCards[0]->getValue();
        for($i=1;$i< count($this->outCards);$i++){
            if($this->outCards[$i]->getValue()!=$v1){
                return false;
            }
        }
        return $v1;
    }

    //三带一 4张牌
    private function isThreeOne(){
        $count = count($this->outCards);
        if( $count !=4 ) return false;
        $temp = [];
        for($i=0;$i<$count;$i++){
            $v = $this->outCards[$i]->getValue();
            if(array_key_exists($v,$temp)){
                $temp[$v]++;
            }else{
                $temp[$v] = 1;
            }
        }
        return array_search(3,$temp);                
    }

    //三带二 5张牌
    private function isThreeTwo(){
        $count = count($this->outCards);
        
        if( $count !=5 ) return false;
        $temp = [];
        for($i=0;$i<$count;$i++){
            $v = $this->outCards[$i]->getValue();
            if(array_key_exists($v,$temp)){
                $temp[$v]++;
            }else{
                $temp[$v] = 1;
            }
        }

        if(count($temp)!=2) return false;
        return array_search(3,$temp);                
    }

    //单顺 最少5张连续牌 不会大于12张
    private function isQueue(){
        
        $count = count($this->outCards);
        if($count>12 || $count<5) return false;
        $v1 = $this->outCards[0]->getValue();
        $vn = $this->outCards[$count-1]->getValue();        
        //最后一张牌的牌值不能大于2的牌值
        if($vn>=12) return false;

        $s1 = ($v1+$vn)*$count/2;        
        
        $s2 = 0;
        $temp = [];
        for($i=0;$i<$count;$i++){
            $v = $this->outCards[$i]->getValue();
            $temp[$v] = 1;
            $s2+= $v;
        }
        if(count($temp)!=$count) return false;

        if($s1!=$s2) return false;
        return $v1;        
    }

    //双顺 牌数是2倍数 最少6张牌 6-8-10-12-14-16-18-20
    private function isDoubleQueue(){
        $count = count($this->outCards);
        if($count<6 || $count%2!==0) return false;        
        $v1 = $this->outCards[0]->getValue();
        $vn = $this->outCards[$count-1]->getValue();        
        //最后一张牌的牌值不能大于2的牌值
        if($vn>=12) return false;
      
        $s1 = ($v1+$vn)*$count/2/2;        
        $s2 = 0;
        $temp=[];
        for($i=0;$i<$count;$i+=2){
            $v = $this->outCards[$i]->getValue();
            $temp[$v] =1;
            $s2+=$v;
        }
        if(count($temp)*2!=$count) return false;        
        if($s1!=$s2) return false;
        return $v1;
    }

    //三顺 牌数是3倍数 最少6张牌 333 444  6-9-12-15-18
    private function isThreeQueue(){
        $count = count($this->outCards);
        if($count<6 || $count%3!==0) return false;        
        $v1 = $this->outCards[0]->getValue();
        $vn = $this->outCards[$count-1]->getValue();        
        //最后一张牌的牌值不能大于2的牌值
        if($vn>=12) return false;
        
        $s1 = ($v1+$vn)*$count/2/3;
        $s2 = 0;
        $temp=[];
        for($i=0;$i<$count;$i+=3){
            $v = $this->outCards[$i]->getValue();
            $temp[$v] =1;
            $s2+=$v;
        }        
        if(count($temp)*3!=$count) return false;        
        if($s1!=$s2) return false;
        return $v1;
    }

    //飞机带单翅 牌数是4倍数 最少8张牌  8-12-16-20
    private function isPlainOne(){       
        $count = count($this->outCards);
        if($count<8 || $count%4!==0) return false;        
        $temp=[];
        $temp1=[];
        for($i=0;$i<$count;$i++){
            $v = $this->outCards[$i]->getValue();
            if(array_key_exists($v,$temp)){
                $temp[$v]++;            
                if($temp[$v]==3){
                    $temp1[] = $v;
                }
            }else{
                $temp[$v] =1;            
            }            
        } 
                        
        $n1 = $count/4;
        if( count($temp1) !=$n1) return false;
        //p($temp1);
        //判断飞机是否是连接的
        $v1 = $temp1[0];
        $vn = $temp1[$n1-1];
        if($vn>=12) return false;
        $s1 = ($v1+$vn)*$n1/2;
        $s2 = array_sum($temp1);        
        if($s1!=$s2) return false;
        return $v1;
    }

    //飞机带双翅 牌数是5倍数 最少10张 10-15-20
    private function isPlainTwo(){
        $count = count($this->outCards);
        if($count<10 || $count%5!==0) return false;        
        $temp=[];
        $temp1=[];
        
        for($i=0;$i<$count;$i++){
            $v = $this->outCards[$i]->getValue();
            if(array_key_exists($v,$temp)){
                $temp[$v]++;            
                if($temp[$v]==3){
                    $temp1[] = $v;
                }
            }else{
                $temp[$v] =1;            
            }            
        } 
        
        $n1 = $count/5;
        if( count($temp1) !=$n1) return false;
        foreach($temp as $value){
            if($value<2 || $value>3){
                return false;
            }
        }                
        //判断飞机是否是连接的
        $v1 = $temp1[0];
        $vn = $temp1[$n1-1];
        if($vn>=12) return false;
        $s1 = ($v1+$vn)*$n1/2;
        $s2 = array_sum($temp1);        
        if($s1!=$s2) return false;
        return $v1;

    }
}